/**
 * 基础形状演员类
 */

 import * as THREE from "./three.js/build/three.module.js";

 import { CapsuleGeometry } from "./A3Geometrys.js";
 import A3Actor from "./A3Actor.js";
 import { getMeshShape, isNull } from "./A3Common.js";
 
 const BasicShapeTypes = {
   Box:"Box",
   Capsule:"Capsule",
   Cone:"Cone",
   Cylinder:"Cylinder",
   Sphere:"Sphere",
   Torus:"Torus",
   Plane:"Plane",
 }
 
 // 生成基础图形Mesh
 function createBasicShapeMesh( type, parameters ) {
   
   let mesh;
 
   switch( type ) {
     
     case "Box":
 
       var sx = parameters[0] &&  parameters[0] > 0 ? parameters[0] : 1;
       var sy = parameters[1] &&  parameters[1] > 0  ? parameters[1] : 1;
       var sz = parameters[2] &&  parameters[2] > 0  ? parameters[2] : 1;
 
       mesh = new THREE.Mesh( new THREE.BoxGeometry( sx, sy, sz ) );
       mesh.position.set( 0, sy / 2, 0 );
 
       break;
     case "Cylinder":
 
       var radiusTop = parameters[0] &&  parameters[0] > 0 ? parameters[0] : .5;
       var radiusBottom = parameters[1] &&  parameters[1] > 0  ? parameters[1] : .5;
       var height = parameters[2] &&  parameters[2] > 0  ? parameters[2] : 1;
 
       mesh = new THREE.Mesh( new THREE.CylinderGeometry( radiusTop, radiusBottom, height, 24 ) );
       mesh.position.set( 0, height / 2, 0 );
 
       break;
     case "Sphere":
 
       var radius = parameters[0] &&  parameters[0] > 0 ? parameters[0] : .5;
 
       mesh = new THREE.Mesh( new THREE.SphereGeometry( radius, 24, 24 ) );
       mesh.position.set( 0, radius, 0 );
 
       break;
     case "Cone":
 
       var radius = parameters[0] &&  parameters[0] > 0 ? parameters[0] : .5;
       var height = parameters[1] &&  parameters[1] > 0 ? parameters[1] : 1;
 
       mesh = new THREE.Mesh( new THREE.ConeGeometry( radius, height, 18 ) );
       mesh.position.set( 0, radius, 0 );
 
       break;
     case "Capsule":
 
       var radius = parameters[0] &&  parameters[0] > 0 ? parameters[0] : .5;
       var height = parameters[1] &&  parameters[1] > 0 ? parameters[1] : 1;
 
       mesh = new THREE.Mesh( new CapsuleGeometry( radius, height, 18 ) );
       mesh.position.set( 0, height * 0.5 + radius, 0 );
 
       break;
 
     case "Torus":
 
       var radius = parameters[0] && parameters[0] > 0 ? parameters[0] : 1;
       var tube = parameters[1] && parameters[1] > 0 ? parameters[1] : .4;
 
       const torusGeometry = new THREE.TorusGeometry( radius, tube, 18, 18 ) ;
       torusGeometry.rotateX( - Math.PI / 2 );
       mesh = new THREE.Mesh( torusGeometry );
 
       mesh.position.set( 0, tube, 0 );
       // mesh.quaternion.setFromAxisAngle( new THREE.Vector3( 1, 0, 0 ), -Math.PI / 2 );
 
       break;
 
     case "Plane":
 
       var width = parameters[0] && parameters[0] > 0 ? parameters[0] : 3;
       var height = parameters[1] && parameters[1] > 0 ? parameters[1] : 3;
 
       const planeGeometry = new THREE.PlaneGeometry( width, height, 4, 4 );
       planeGeometry.rotateX( - Math.PI / 2 );
       mesh = new THREE.Mesh( planeGeometry );
       // 物理模型默认高度(Z)值为0.002
       mesh.position.set( 0, 0.002, 0 );
 
       break;
 
     default:
       console.error( "不支持的形状类型:", type );
       break;
   }
 
   return mesh;
 
 }
 
 // 基础图形
 class A3BasicShape extends A3Actor{
   
   name="basic_shape";
 
   constructor( type="Box", ...parameters ) {
     super();
 
     const mesh = createBasicShapeMesh( type, parameters );
     this.threeObject = mesh;
     this.physicsShape = getMeshShape( mesh, new THREE.Vector3( 1, 1, 1 ), true );
     // this.setFromMesh( mesh, 1.0 );
     this.setMaterial();
     this.type = type;
     
   }
 
 }
 
 // 物体产生器
 class A3ObjectMaker extends A3Actor{
 
   isRandom = true;
   // 可视化
   boxSize = 1;
   boxColor = 0x1982cc;
   boxOpacity = 0.8;
 
   visible = true;
 
   // 物体参数
   objectMass = 1;
   // objectSize = 1;
 
   clock = new THREE.Clock();
   tCount = 0;
   speed = 1;  // 生产速度 单位秒
 
   constructor( position, size=1 ) {
     super();
 
     if( isNull( position ) ) {
       position = new THREE.Vector3( 0, 0, 0 );
     }
 
     const boxMatrial = new THREE.MeshPhongMaterial( { color: this.boxColor, transparent: true, opacity: this.boxOpacity } );
     this.threeObject = new THREE.Mesh( new THREE.BoxGeometry( size, size, size ), boxMatrial );
 
     this.threeObject.position.copy( position );
     this.position.copy( position );
     this.boxSize = size;
   }
 
   createObject( type="Box" ) {
     const newObject = new A3BasicShape( type, this.boxSize, this.boxSize, this.boxSize );
     // newObject.setPosition( this.position );
     newObject.recyclable = true;
     // newObject.setMass( this.objectMass );
     newObject.init( this.objectMass, this.position, this.quaternion );
 
     this.parent.addActor( newObject );
   }
 
   update() {
     this.tCount += this.clock.getDelta();
 
     if( this.tCount >= this.speed ) {
       this.createObject();
       this.tCount = 0;
     }
   }
 
 }
 
 // 物体回收器
 class A3ObjectRecycler extends A3Actor {
   name='recycler';
   type='recycler';
   // 可视化
   boxSize = 1;
   boxColor = 0x19cc82;
   boxOpacity = 0.8;
 
   visible = true;
 
   constructor( position, size=1 ) {
 
     super();
 
     if( isNull( position ) ) {
       position = new THREE.Vector3( 0, 0, 0 );
     }
 
     const boxMatrial = new THREE.MeshPhongMaterial( { color: this.boxColor, transparent: true, opacity: this.boxOpacity } );
     this.threeObject = new THREE.Mesh( new THREE.BoxGeometry( size, size, size ), boxMatrial );
 
     this.threeObject.position.copy( position );
     this.position.copy( position );
     this.boxSize = size;
 
   }
 
   inRecyclerBox( position ) {
 
     var isInBox = true;
     if(Math.abs( position.x - this.position.x ) > this.boxSize / 2 ) {
       isInBox = false;
     }
 
     if(Math.abs( position.y - this.position.y ) > this.boxSize / 2 ) {
       isInBox = false;
     }
 
     if(Math.abs( position.z - this.position.z ) > this.boxSize / 2 ) {
       isInBox = false;
     }
 
     return isInBox;
   }
 
   update() {
 
     const actors = this.parent.actors;
 
     actors.forEach( actor=>{
       if( actor.recyclable && this.inRecyclerBox( actor.position ) ) {
         this.parent.removeActor( actor );
       }
     })
 
   }
 }
 
 export default A3BasicShape;
 
 export { 
   BasicShapeTypes,
   A3ObjectMaker,
   A3ObjectRecycler,
 };